package com.zoe.onelink.sentinel.handler;

import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.cloud.sentinel.SentinelProperties;
import com.alibaba.cloud.sentinel.custom.SentinelDataSourceHandler;
import com.alibaba.cloud.sentinel.datasource.RuleType;
import com.alibaba.cloud.sentinel.datasource.config.DataSourcePropertiesConfiguration;
import com.alibaba.cloud.sentinel.datasource.config.NacosDataSourceProperties;
import com.alibaba.nacos.common.utils.MapUtil;
import com.zoe.onelink.sentinel.property.OnelinkSentinelProperties;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.env.Environment;

import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2022</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2022-04-18
 */
public class OnelinkNacosSentinelDataSourceHandler extends SentinelDataSourceHandler {

    private final DefaultListableBeanFactory beanFactory;
    private final SentinelProperties sentinelProperties;
    private final Environment env;

    public OnelinkNacosSentinelDataSourceHandler(DefaultListableBeanFactory beanFactory, SentinelProperties sentinelProperties, Environment env) {
        super(beanFactory, sentinelProperties, env);
        this.beanFactory = beanFactory;
        this.sentinelProperties = sentinelProperties;
        this.env = env;
    }

    @Override
    public void afterSingletonsInstantiated() {
        OnelinkSentinelProperties onelinkSentinelProp = this.beanFactory.getBean(OnelinkSentinelProperties.class);
        Map<String, DataSourcePropertiesConfiguration> datasource = this.sentinelProperties.getDatasource();
        List<RuleType> rules = onelinkSentinelProp.getRules();
        if (!onelinkSentinelProp.isAutoCreateDatasource()
                || rules.isEmpty()
                || !MapUtil.isEmpty(datasource)) {
            return;
        }
        if (datasource == null) {
            datasource = new TreeMap<>();
            this.sentinelProperties.setDatasource(datasource);
        }
        for (RuleType rule : rules) {
            String dsName = String.format("ds-nacos-%s", rule.name().toLowerCase(Locale.ROOT));
            datasource.put(dsName, this.createNacosConfigProperties(rule));
        }
        super.afterSingletonsInstantiated();
    }

    /**
     * 创建Nacos Sentinel规则
     */
    private DataSourcePropertiesConfiguration createNacosConfigProperties(RuleType ruleType) {
        DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
        String serverName = this.env.getProperty("spring.application.name");
        NacosConfigProperties nacosConfigProperties = this.beanFactory.getBean(NacosConfigProperties.class);
        DataSourcePropertiesConfiguration degradeConfig = new DataSourcePropertiesConfiguration();
        NacosDataSourceProperties nacosDataSourceProp = new NacosDataSourceProperties();
        BeanUtils.copyProperties(nacosConfigProperties, nacosDataSourceProp);
        degradeConfig.setNacos(nacosDataSourceProp);
        nacosDataSourceProp.setDataId(String.format("%s-%s-rules", serverName, ruleType.name().toLowerCase(Locale.ROOT)));
        nacosDataSourceProp.setGroupId("SENTINEL_GROUP");
        nacosDataSourceProp.setRuleType(ruleType);
        dataSourcePropertiesConfiguration.setNacos(nacosDataSourceProp);
        return dataSourcePropertiesConfiguration;
    }

}
